package org.chs.ts.batch.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.util.Strings;
import org.chs.ts.base.batch.exec.entity.BatchDailyBasicTaskStepExec;
import org.chs.ts.batch.mapper.BatchDailyBasicTaskStepExecMapper;
import org.chs.ts.batch.service.IBatchDailyBasicTaskStepExecService;
import org.chs.ts.batch.util.RedisBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Description: batch_clear_basic_task_step_exec
 * @Author: jeecg-boot
 * @Date: 2024-04-09
 * @Version: V1.0
 */
@Service
@Slf4j
public class BatchDailyBasicTaskStepExecServiceImpl extends ServiceImpl<BatchDailyBasicTaskStepExecMapper, BatchDailyBasicTaskStepExec> implements IBatchDailyBasicTaskStepExecService {

    private final String CLASS_NAME = this.getClass().getSimpleName();

    @Resource
    RedisBuilder redisBuilder;

    private final String UPDATE_KEY = "UpdateTaskDailyStepExec";

    private final int updateCount = 3;
    @Resource
    BatchDailyBasicTaskStepExecMapper TaskDailyStepExecMapper;

    @Override
    public boolean updateTaskDailyStepByObj(String taskExecid, String serverIP, String serverName, String startTime, String endTime, String rtnCode
            , String execStatus) {
        boolean updateResult = false;
        String methodName = "updateTaskDailyStepByObj";

        int i = 0;
        LambdaQueryWrapper<BatchDailyBasicTaskStepExec> queryWrapper = new LambdaQueryWrapper<BatchDailyBasicTaskStepExec>()
                .eq(BatchDailyBasicTaskStepExec::getTaskExecid, taskExecid)
                .eq(BatchDailyBasicTaskStepExec::getServerIp, serverIP)
                .eq(BatchDailyBasicTaskStepExec::getServerName, serverName)
                .eq(BatchDailyBasicTaskStepExec::getStartTime, startTime)
                .eq(BatchDailyBasicTaskStepExec::getEndTime, endTime)
                .eq(BatchDailyBasicTaskStepExec::getRtnCode, rtnCode)
                .eq(BatchDailyBasicTaskStepExec::getExecStatus, execStatus);
        do {
            // 获取数据更新锁
            if (redisBuilder.checkUpdateRedisLock(UPDATE_KEY + taskExecid)) {
                log.info(CLASS_NAME + methodName + " method: taskExecId:" + taskExecid + " serverIP:" + serverIP + " serverName:" + serverName + " " +
                        "startTime:" + startTime + " endTime:" + endTime + " rtnCode:" + rtnCode + " execStatus:" + execStatus);
                TaskDailyStepExecMapper.updateTaskDailyStepByObj(taskExecid, Strings.isBlank(serverIP) ? serverIP : "",
                        Strings.isBlank(serverName) ? serverName : "", Strings.isBlank(startTime) ? startTime : "", Strings.isBlank(endTime) ?
                                endTime : "", rtnCode, execStatus);
                redisBuilder.unUpdateRedisLock(UPDATE_KEY + taskExecid);
                updateResult = true;
                break;
            }

            // 获取数据库更新锁失败 确认数据是否已更新
            if (TaskDailyStepExecMapper.selectCount(queryWrapper) > 0) {
                log.info(CLASS_NAME + methodName + " method: taskExecId:" + taskExecid + "已更新具体参数如下 [serverIP:" + serverIP + " serverName:"
                        + serverName + " startTime:" + startTime + " endTime:" + endTime + " rtnCode:" + rtnCode + " execStatus:" + execStatus + "]");
                break;
            }
            redisBuilder.sleepThread();

            i++;
        } while (i < updateCount);

        if (i == updateCount) {
            log.info(CLASS_NAME + methodName + " method: taskExecId:" + taskExecid + "更新失败存在数据库redis更新锁 具体参数如下[serverIP:" + serverIP + " " +
                    "serverName:" + serverName + " startTime:" + startTime + " endTime:" + endTime + " rtnCode:" + rtnCode + " execStatus:" + execStatus + "]");

        }

        return updateResult;

    }


    @Override
    public boolean updateByObject(BatchDailyBasicTaskStepExec obj) {
        boolean updateResult = false;
        String methodName = "updateByObject";

        int i = 0;

        do {
            // 获取数据更新锁
            if (redisBuilder.checkUpdateRedisLock(UPDATE_KEY + obj.getTaskExecid())) {
                log.info(CLASS_NAME + methodName + " method: taskExecId:" + obj.getTaskExecid());
                TaskDailyStepExecMapper.updateById(obj);
                redisBuilder.unUpdateRedisLock(UPDATE_KEY + obj.getTaskExecid());
                updateResult = true;
                break;
            }

            // 获取数据库更新锁失败 确认数据是否已更新
            if (TaskDailyStepExecMapper.selectCount(new LambdaQueryWrapper<BatchDailyBasicTaskStepExec>().eq(BatchDailyBasicTaskStepExec::getTaskExecid,obj.getTaskExecid())) > 0) {
                log.info(CLASS_NAME + methodName + " method: taskExecId:" + obj.getTaskExecid() + "已更新");
                break;
            }
            redisBuilder.sleepThread();

            i++;
        } while (i < updateCount);

        if (i == updateCount) {
            log.info(CLASS_NAME + methodName + " method: taskExecId:" + obj.getTaskExecid() + "更新失败存在数据库redis更新锁");

        }

        return updateResult;
    }


    @Override
    public boolean updateByTaskExecid(String taskExecid, String execStatus) {
        boolean updateResult = false;
        String methodName = "updateByTaskExecid";

        int i = 0;

        do {
            // 获取数据更新锁
            if (redisBuilder.checkUpdateRedisLock(UPDATE_KEY + taskExecid)) {
                log.info(CLASS_NAME + methodName + " method: taskExecId:" + taskExecid);
                BatchDailyBasicTaskStepExec obj = TaskDailyStepExecMapper.selectOne(new LambdaQueryWrapper<BatchDailyBasicTaskStepExec>().eq(BatchDailyBasicTaskStepExec::getTaskExecid, taskExecid));
                obj.setExecStatus(execStatus);
                TaskDailyStepExecMapper.updateById(obj);
                redisBuilder.unUpdateRedisLock(UPDATE_KEY + obj.getTaskExecid());
                updateResult = true;
                break;
            }

            // 获取数据库更新锁失败 确认数据是否已更新
            if (TaskDailyStepExecMapper.selectCount(new LambdaQueryWrapper<BatchDailyBasicTaskStepExec>().eq(BatchDailyBasicTaskStepExec::getTaskExecid,taskExecid).eq(BatchDailyBasicTaskStepExec::getExecStatus,execStatus)) > 0) {
                log.info(CLASS_NAME + methodName + " method: taskExecId:" + taskExecid + "已更新");
                break;
            }
            redisBuilder.sleepThread();

            i++;
        } while (i < updateCount);

        if (i == updateCount) {
            log.info(CLASS_NAME + methodName + " method: taskExecId:" + taskExecid + "更新失败存在数据库redis更新锁");

        }

        return updateResult;
    }

    @Override
    public List<BatchDailyBasicTaskStepExec> getTask(String batchSysCode, String execDate, String currentHHmmss) {
        return TaskDailyStepExecMapper.getTask(batchSysCode,execDate,currentHHmmss);
    }
}
